package com.wa.graphql;

import com.wa.graphql.exception.CustomDataFetcherExceptionHandler;
import com.wa.graphql.schemas.TestSchema;
import graphql.GraphQL;
import graphql.Scalars;
import graphql.execution.AsyncExecutionStrategy;
import graphql.schema.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import static graphql.schema.GraphQLObjectType.newObject;

/**
 * graphql.demo. GraphQL provider.
 *
 * @author xuxd
 * @date 2021-06-06 18:48:32
 * @description graphql.demo
 **/
@Component
public class GraphQLProvider {

    private GraphQL graphQL;

    @Resource
    TestSchema testSchema;

    @Bean
    public GraphQL graphQL() {
        return graphQL;
    }

    @PostConstruct
    public void init() {
        GraphQLObjectType.Builder query = newObject().name("query");
//        {
//            "query":"{queryById(id:1){data{id,name,code,createTime,searchDate}}}",
//                "extraParam":{
//            }
//        }
        query.field(testSchema.queryById((getGraphqlOutputType(testSchema.getItemOutputType(), "queryById"))));
//        {
//            "query":"{queryItemList{data{itemList{id,name,code,createTime,searchDate},total}}}",
//                "extraParam":{
//
//            }
//        }
        query.field(testSchema.queryItemList((getGraphqlOutputType(testSchema.getItemListOutputType(), "queryItemList"))));
        GraphQLSchema schema = GraphQLSchema.newSchema().query(query.build()).build();
        this.graphQL = GraphQL.newGraphQL(schema).queryExecutionStrategy(new AsyncExecutionStrategy(new CustomDataFetcherExceptionHandler())).build();
    }

    /**
     * 动态指定输出返回数据结果
     * 处理集合数据
     *
     * @param outputType
     * @param name       注册名称需要唯一
     * @return
     */
    private GraphQLObjectType getOutputType(GraphQLOutputType outputType, String name) {
        return newObject()
                .name(name)
                .field(GraphQLFieldDefinition.newFieldDefinition().name("pageNo").type(Scalars.GraphQLInt))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("pageSize").type(Scalars.GraphQLInt))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("totalCount").type(Scalars.GraphQLInt))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("totalPage").type(Scalars.GraphQLInt))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("code").type(Scalars.GraphQLInt))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("message").type(Scalars.GraphQLString))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("data").type(new GraphQLList(outputType))).build();
    }

    /**
     * 动态指定输出返回数据结果(没有分页)
     * 处理单对象数据
     *
     * @param outputType
     * @param name
     * @return
     */
    private GraphQLObjectType getGraphqlOutputType(GraphQLOutputType outputType, String name) {
        return newObject()
                .name(name)
                .field(GraphQLFieldDefinition.newFieldDefinition().name("code").type(Scalars.GraphQLInt))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("message").type(Scalars.GraphQLString))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("data").type(outputType)).build();
    }

}
